library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.0     ✓ purrr   0.3.3
✓ tibble  3.0.0     ✓ dplyr   0.8.5
✓ tidyr   1.0.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ───────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(cowplot)

********************************************************
Note: As of version 1.0.0, cowplot does not change the
  default ggplot2 theme anymore. To recover the previous
  behavior, execute:
  theme_set(theme_cowplot())
********************************************************
library(lubridate)

Attaching package: ‘lubridate’

The following object is masked from ‘package:cowplot’:

    stamp

The following objects are masked from ‘package:dplyr’:

    intersect, setdiff, union

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(mgcv)
Loading required package: nlme

Attaching package: ‘nlme’

The following object is masked from ‘package:dplyr’:

    collapse

This is mgcv 1.8-31. For overview type 'help("mgcv-package")'.
theme_set(theme_cowplot())
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')

Particles Only

Read In Data

bes<- read_csv("dataOut/binned_EachSize.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
bds <- read_csv("dataOut/binned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
ues <- read_csv("dataOut/unbinned_EachSize.csv")
Parsed with column specification:
cols(
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = ""),
  depth = col_double(),
  psd_gam = col_double(),
  vol = col_double(),
  sizeclass = col_character(),
  lb = col_double(),
  ub = col_double(),
  binsize = col_double(),
  TotalParticles = col_double(),
  nparticles = col_double(),
  n_nparticles = col_double(),
  biovolume = col_double(),
  speed = col_double(),
  flux = col_double(),
  flux_fit = col_double(),
  GamPredictTP = col_double()
)
uds <- read_csv("dataOut/unbinned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.

Summary Statistics

PlotNParticles <- uds %>% 
  ggplot(aes(x = tot_nparticles, y = depth, col = profile)) +
 facet_wrap(~project) +
 geom_point(alpha = 0.3, shape = 1) +
scale_y_reverse() + scale_x_log10()

PlotNParticles

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(tot_nparticles~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(tot_nparticles ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

#FSG4 <- gam(tot_nparticles~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)    9.002      0.106   84.96   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value  
s(depth) 1.204  1.366 3.346  0.0874 .
s(Day)   1.512  1.761 3.001  0.0386 *
s(Hour)  1.579  2.000 2.713  0.0389 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.183   Deviance explained = 24.2%
GCV = 0.73885  Scale est. = 0.67365   n = 60
#summary(FSG2)
#summary(FSG3)
#summary(FSG4)

summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.07590024
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.05267319
summary(FSG3)$r.sq
[1] 0.0542546

But there is between projects:

ProjGam <- gam(tot_nparticles~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))

summary(ProjGam)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + factor(project)

Parametric coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)          8.9983     0.4445   20.24   <2e-16 ***
factor(project)P16  17.0001     1.3754   12.36   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
         edf Ref.df     F p-value  
s(depth)   1      1 3.552   0.064 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =    0.7   Deviance explained = 70.9%
GCV = 12.411  Scale est. = 11.855    n = 67
PlotPSDmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = psd, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) 

PlotParticlesmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = tot_nparticles, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  scale_x_log10() + theme(legend.position = "none")

PlotFluxmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = tot_flux_fit, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  scale_x_log10() + theme(legend.position = "none")



plot_grid(
  PlotParticlesmany,
  PlotPSDmany,
  rel_widths = c(2, 3)
  )


ggsave("figures/ParticlesPSDMany.png")
Saving 12 x 7.41 in image
ggsave("figures/ParticlesPSDMany.svg")
Saving 12 x 7.41 in image
bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(psd~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(psd ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(psd ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG4 <- gam(psd~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.96083    0.01988  -199.3   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F p-value    
s(depth) 1.713  1.917 56.197 5.5e-15 ***
s(Day)   1.000  1.000  1.078  0.3036    
s(Hour)  1.604  2.000  3.049  0.0285 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.635   Deviance explained = 66.1%
GCV = 0.026006  Scale est. = 0.023702  n = 60
#summary(FSG2)
#summary(FSG3)
summary(FSG4)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.96083    0.01995  -198.5   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.715  1.919 55.141 7.66e-15 ***
s(Hour)  1.565  2.000  2.497   0.0488 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.632   Deviance explained = 65.2%
GCV = 0.02572  Scale est. = 0.023885  n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.03804023
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] -0.004905911
summary(FSG3)$r.sq
[1] 0.6015425

Not a significant difference in PSD with respect to time.

But there is between projects:

ProjGam <- gam(psd~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))

summary(ProjGam)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + factor(project)

Parametric coefficients:
                   Estimate Std. Error  t value Pr(>|t|)    
(Intercept)        -3.96167    0.02491 -159.029   <2e-16 ***
factor(project)P16 -0.19977    0.07708   -2.592   0.0118 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.224  1.398 34.54 2.26e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.437   Deviance explained = 45.6%
GCV = 0.039117  Scale est. = 0.037234  n = 67

I wonder if I can show that the profiles aren’t statistically significanlty different. Or that they are for that matter… I think in that case, I run a gam with and without a parameter for profile… And then quantify the effect size of that parameter

Or follow this Gavin Simpson Post https://fromthebottomoftheheap.net/2017/10/10/difference-splines-i/

or anova.gam {mgcv}

Calculate gams for each profile, and then run anova.gam to see if they are different…

PlotNParticlesEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = tot_nparticles, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  #geom_path(aes(x = tot_nparticles)) +
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(2500, 0)) + scale_x_log10() + scale_color_manual(values = c("gray20", "brown")) +
  labs(x = "Particles/L", y = "depth (m)") +
  theme(legend.position = "none") +
  scale_shape_manual(values = c(1:5)) 

PlotNParticlesEP

I removed one outlyer from p16 for visualization purposes (300 particles/l at surface)

PlotPSDEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = psd, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  geom_path(aes(x = psd_gam)) +
  geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(2500, 0)) + scale_color_manual(values = c("gray20", "brown"))  +
  scale_shape_manual(values = c(1:5)) + labs(y = "")

PlotPSDEP

I may just cow these togther.

plot_grid(PlotNParticlesEP, PlotPSDEP, rel_widths = c(2,3), labels = c("A", "B"))
Removed 611 rows containing missing values (geom_point).Removed 611 rows containing missing values (geom_point).Removed 611 row(s) containing missing values (geom_path).

ggsave("figures/ParticlesAndPSD_ETNPVsP16.svg")
Saving 10 x 4 in image
ggsave("figures/ParticlesAndPSD_ETNPVsP16.png")
Saving 10 x 4 in image
mainParticleComponents <- bds %>%
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  select(project, profile, depth,
         tot_nparticles, small_nparticles, big_nparticles,
         tot_psd = psd, small_psd, big_psd,
         tot_flux_fit, small_flux_fit, big_flux_fit) %>%
  pivot_longer(cols = -c("project", "profile", "depth")) %>%
  separate(name, c("size", "meas")) %>%
  mutate(meas = recode(meas, nparticles = "particles/L")) %>%
  mutate(meas = factor(meas, levels = c("particles/L", "flux", "psd")))
Expected 2 pieces. Additional pieces discarded in 273 rows [7, 8, 9, 16, 17, 18, 25, 26, 27, 34, 35, 36, 43, 44, 45, 52, 53, 54, 61, 62, ...].
PlotFlx <- mainParticleComponents %>% 
  filter(meas != "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size ~ meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + theme(axis.title.x = element_blank(), legend.position = "none", strip.background.y = element_blank(), strip.text.y = element_blank(), plot.margin = unit(c(7,0,7,7), "pt")) + scale_color_manual(values = c("brown", "gray20")) + scale_shape_manual(values = c(1:5)) + theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = 175, color = "darkgreen")

PlotPSD <- mainParticleComponents %>% 
  filter(meas == "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size~meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank(), axis.line.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), plot.margin = unit(c(7,7,26.5,0), "pt")) +
  scale_color_manual(values = c("brown", "gray20")) +  scale_shape_manual(values = c(1:5)) +  theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = 175, color = "darkgreen")

plot_grid(PlotFlx, PlotPSD, rel_widths = c(3, 2))
Removed 246 rows containing missing values (geom_point).Removed 123 rows containing missing values (geom_point).
ggsave("figures/BigVsSmall.svg")
Saving 7.29 x 4.5 in image
ggsave("figures/BigVsSmall.png")
Saving 7.29 x 4.5 in image

Flux small and flux tot track so closely because ag > psd. since the size distribution of the flux sould be PSD + ag (psd is negative in this case). Yo ucan see the variance at the one depth where psd is flatest at the very top.

eg_dataline <- bds %>% 
  filter(profile == "stn_043", depth == 162.5)
eg_slope =  eg_dataline %>% pull(psd)
eg_icp = eg_dataline %>% pull(icp)
eg_vol = eg_dataline %>% pull(vol)

eg_datablock <- bes %>%
  filter(profile == "stn_043", depth == 162.5)


eg_lb = eg_datablock$lb
eg_binsize = eg_datablock$binsize
eg_nnp = exp(eg_icp + log(eg_lb) * eg_slope)

eg_np = eg_nnp * eg_binsize
eg_tp = eg_np * eg_vol
eg_df <- tibble(lb = eg_lb, n_nparticles = eg_nnp, nparticles = eg_np, TotalParticles = eg_tp)


EgNNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = n_nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Binsize & Volume Normalized \n Particles (#/L/mm)")

EgNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Normalized Particles")

EgTP <- eg_datablock %>%
  ggplot(aes(x = lb, y = TotalParticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs( y = "Total Particles Observed (#)")

plot_grid(EgNNP, EgTP, labels = c("A", "B"))
Transformation introduced infinite values in continuous y-axisTransformation introduced infinite values in continuous y-axis
ggsave("figures/ExamplePSD163m.png")
Saving 7.29 x 4.5 in image
ggsave("figures/ExamplePSD163m.svg")
Saving 7.29 x 4.5 in image

Smooth flux and um disaggregation.

bds %>% 
  ggplot(aes(y = depth, x = Flux_Smooth, col = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10()

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(Flux_Smooth~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(Flux_Smooth ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9334   37.21   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.875  1.984 11.823 0.000126 ***
s(Day)   1.756  1.939  2.168 0.094012 .  
s(Hour)  1.114  2.000  1.658 0.059271 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =   0.33   Deviance explained = 38.4%
GCV = 57.811  Scale est. = 52.277    n = 60
summary(FSG2)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9607   36.15   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.869  1.983 11.102 0.000206 ***
s(Day)   1.811  1.964  2.743 0.094614 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =   0.29   Deviance explained = 33.4%
GCV = 60.062  Scale est. = 55.377    n = 60
summary(FSG3)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9944   34.93   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.857  1.979 10.73 0.000277 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.239   Deviance explained = 26.3%
GCV = 62.291  Scale est. = 59.325    n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.03975922
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.05063133
summary(FSG3)$r.sq
[1] 0.2392424
bds %>% filter(project == "ETNP") %>% select(profile, depth, Flux_Smooth) %>% pivot_wider(names_from = profile, values_from = Flux_Smooth)

Something is off. All of the flux profiles are identical. Skip this

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
plt1 <- bds %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = DFP, col = factor(time), shape = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + xlim(c(0.5, 1.5))+ geom_vline(xintercept = 1) +
   scale_color_manual(values = c(rep("black", 5), rep("blue", 5))) + scale_shape_manual(values = rep(1:5, 2))

plotly::ggplotly(plt1)

What the heck is going on with DFP here. Why is it usually > 1 shouldn’t it be less than 1 when flux is decreasing? This very deep increasing flux seems improbable to me. Lets check the smooths. Or only go to 1000m.

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlx <- bds %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + facet_wrap(~project) + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(2500, 0))+
  scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  theme(axis.text.x = element_text(angle = 90)) +
labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d))) +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 20, xmax = 180, ymin = 75, ymax = 500), colour = "red", fill = NA, inherit.aes = FALSE)



pltFlxNoLegend <- pltFlx + theme(legend.position = "none")

pltFlx

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxZoom <- bds %>% filter(project == "ETNP" & depth <= 500 & depth >= 75) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse()+
  #scale_x_log10() +
  scale_x_log10(breaks = c(seq(from = 20, to = 50, by = 10), seq(from = 60, to = 180, by = 20)), limits = c(20, 180)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(values = rep(21:25, 2)) + 
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  theme(axis.text.x = element_text(angle = 90)) +
labs(x = "Smoothed Flux") + theme(legend.position = "none")

pltFlxZoom

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3 <- bds %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), shape = factor(day(time)), fill = hour(time), group = factor(time))) + facet_wrap(~project) + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(2500, 0))+
  scale_x_continuous(limits = c(-4.5, 1)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5})) + theme(legend.pos = "none")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3

#plotly::ggplotly(plt1pos)
#plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)

pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
Removed 15 rows containing missing values (geom_point).Removed 15 row(s) containing missing values (geom_path).
pgTop <- plot_grid(pltFlxNoLegend, pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
Removed 15 rows containing missing values (geom_point).Removed 15 row(s) containing missing values (geom_path).
pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""))
Removed 29 rows containing missing values (geom_point).Removed 29 row(s) containing missing values (geom_path).
pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)

pgBoth


ggsave("figures/FluxDeepDive.png")
Saving 8 x 8 in image
ggsave("figures/FluxDeepDive.svg")
Saving 8 x 8 in image
#plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)

pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
Removed 15 rows containing missing values (geom_point).Removed 15 row(s) containing missing values (geom_path).
pgTop <- plot_grid(pltFlxNoLegend + ylim(c(1000, 0)), pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
Removed 42 rows containing missing values (geom_point).Removed 42 row(s) containing missing values (geom_path).
pgBottom <- plot_grid(pltDelta3 + ylim(c(1000, 0)), pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""))
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
Removed 56 rows containing missing values (geom_point).Removed 56 row(s) containing missing values (geom_path).
pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)

pgBoth


ggsave("figures/FluxShallowDive.png")
Saving 8 x 8 in image
ggsave("figures/FluxShallowDive.svg")
Saving 8 x 8 in image

Test for day to day and hourly variability

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

DFG1 <- gam(DF/DZ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

DFG2 <- gam(DF/DZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

DFG3 <- gam(DF/DZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(DFG1)

Family: gaussian 
Link function: identity 

Formula:
DF/DZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -0.1001     0.0171  -5.854 2.94e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.911  1.992 22.994 7.83e-08 ***
s(Day)   1.870  1.983  7.097  0.00126 ** 
s(Hour)  1.292  2.000  2.013  0.05235 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.514   Deviance explained = 55.5%
GCV = 0.019516  Scale est. = 0.017541  n = 60
summary(DFG2)

Family: gaussian 
Link function: identity 

Formula:
DF/DZ ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.10008    0.01769  -5.657 5.67e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.902  1.990 22.110 1.37e-07 ***
s(Day)   1.904  1.991  6.768  0.00339 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.479   Deviance explained = 51.3%
GCV = 0.020417  Scale est. = 0.018782  n = 60
summary(DFG3)

Family: gaussian 
Link function: identity 

Formula:
DF/DZ ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.10008    0.01944  -5.149 3.37e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.878  1.985 19.24 9.12e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.371   Deviance explained = 39.1%
GCV = 0.023812  Scale est. = 0.02267   n = 60
summary(DFG1)$r.sq - summary(DFG2)$r.sq
[1] 0.03441623
summary(DFG2)$r.sq - summary(DFG3)$r.sq
[1] 0.1078441
summary(DFG3)$r.sq
[1] 0.3713016
plot(DFG1)

#Osps

(u mol C / m^3 / day)

bds %>% 
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), shape = factor(day(time)), fill = hour(time), group = factor(time))) + facet_wrap(~project) + geom_point(size = 2) + scale_y_reverse(limits = c(2500, 0)) + geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + labs(x = bquote("Flux Size Shift"~μmol/m^3/day)) +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue")

#ggsave("..figures/FluxSizeShift.svg"

 ggsave("figures/FluxSizeShift.png")
Saving 7.29 x 4.5 in image
 ggsave("figures/FluxSizeShift.svg")
Saving 7.29 x 4.5 in image

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

OZG1 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

OZG2 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

OZG3 <- gam(ospsDZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(OZG1)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.024817   0.002245   11.05 1.48e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
            edf Ref.df     F  p-value    
s(depth) 1.8892  1.988 8.422 0.000434 ***
s(Day)   1.8718  1.983 6.012 0.003119 ** 
s(Hour)  0.5513  2.000 0.396 0.243644    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.347   Deviance explained = 39.5%
GCV = 0.00033186  Scale est. = 0.00030248  n = 60
summary(OZG2)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.02482    0.00226   10.98 1.67e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
          edf Ref.df     F  p-value    
s(depth) 1.89  1.988 8.429 0.000428 ***
s(Day)   1.89  1.988 6.748 0.003790 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.338   Deviance explained = 38.1%
GCV = 0.00033306  Scale est. = 0.00030653  n = 60
summary(OZG3)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.024817   0.002479   10.01 3.55e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.872  1.984 7.338 0.000983 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.204   Deviance explained = 22.9%
GCV = 0.00038738  Scale est. = 0.00036884  n = 60
summary(OZG1)$r.sq - summary(OZG2)$r.sq
[1] 0.008753478
summary(OZG2)$r.sq - summary(OZG3)$r.sq
[1] 0.1344912
summary(OZG3)$r.sq
[1] 0.2038316
bds %>% filter(project == "P16") %>%
  ggplot(aes(y = depth, x = ospsDZ)) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(500, 0)) + geom_vline(xintercept = 0)

Trap data

trapFlux3 <- read_csv("dataOut/fluxMS_distilled.csv")
Parsed with column specification:
cols(
  Class = col_character(),
  Depth = col_double(),
  TrapID = col_character(),
  TrapType = col_character(),
  SampleType = col_character(),
  C_flux = col_double(),
  C_flux_umol = col_double()
)
UVPFluxComb <- read_csv("dataOut/CombinedProfileFluxEst_DS.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  Flux = col_double()
)
trapFlux3
UVPFluxComb

fluxMS_distilled_toPlot <- trapFlux3 %>%
  mutate(SampleType = recode(SampleType, `plus.p` = "plus-particles", top = "top-collector"))
UVPFluxComb %>%
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType),
             colour = "black", stroke = 1, size = 5, data = fluxMS_distilled_toPlot) +
  geom_point(aes(x = Flux), size = 3, shape = 21, color = "white", fill = "black") +
  geom_point(aes(x = -1, y = -1, size = "UVP")) + # dummy point for the legend
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1, name = "") +
  ylab("Depth (m)") + xlab("Flux µmolC/m^2/day") +
  guides(fill = guide_legend(override.aes = list(shape = 21))) +
  theme_cowplot() + 
  theme(
        legend.position = c(0.5, 0.4),
        legend.box.background = element_rect(color = "black", size = 0.5),
        legend.margin = margin(-10, 5, 10, 5)
  ) +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 15, xmax = 32, ymin = 45, ymax = 195), colour = "red", fill = NA, inherit.aes = FALSE)
ggsave("figures/FittedFlux.png")
Saving 7.29 x 4.5 in image
ggsave("figures/FittedFlux.svg")
Saving 7.29 x 4.5 in image

Weber Bianchi Figs

SameGam <- gam(TotalParticles ~s(log(lb), log(depth), by = factor(time)), offset = log(vol * binsize), family = nb(),
    data = bes %>% filter(project == "ETNP"))
Pred <- exp(predict(SameGam, Expanded))
Pred <- exp(predict(SameGam, Expanded))

meanBese <- ToPlot %>% filter(lb <= 2) %>% group_by(lb, depth) %>% summarize(nparticles = mean(nparticles), nnparticles = mean(nnparticles))

WBColorMap <- meanBese%>%
   ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c(name = "log10(number density \n (normalized))") + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue")
WBColorMap

Average of everything

meanBese043 <- ToPlot %>% filter(lb <= 2, time == "2017-01-13 11:51:31")

meanBese043%>%
   ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c() + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 175, color = "darkgreen")

Just 043

mbGam <- meanBese %>% group_by(depth)  %>% nest() %>%
  mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% 
  mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2]))
mbGam %>% ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept =  950, color = "darkblue")

mbGam <- meanBese043 %>% group_by(depth)  %>% nest() %>%
  mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% 
  mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2]))
pWBPSD <- mbGam %>% ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse()  + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept =  950, color = "darkblue")
pWBPSD

Fig 5 WB

bds %>% filter(profile == “stn_043”, depth <= 2000) %>% ggplot(aes(x = psd_gam, xmin = psd_gam - psd_seg * 2, xmax = psd_gam + psd_seg * 2, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = “darkgreen”) + geom_hline(yintercept = 950, color = “darkblue”) + geom_ribbon(alpha = 0.2) + labs(x = “PSD slope”)

All of them

bds %>% filter(profile == "stn_043", depth <= 2000) %>% ggplot(aes(x = psd_gam, xmin = psd_gam - psd_seg * 2, xmax = psd_gam + psd_seg * 2, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue") + geom_ribbon(alpha = 0.2) + labs(x = "PSD slope")

043 only

bds %>% filter(profile == "stn_043", depth <= 2000, depth > 175) %>% ggplot(aes(x = small_biovolume, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue") + geom_point()

ubDf0 <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global)
ubDf <- ubDf0 %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)
photicBiomass <- ubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
ubDf <- ubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object length
ubDf %>% ggplot(aes(x = nbiomass, y = depth , group = time, col = time)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1))

ubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- ubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
ubDf <- ubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
ubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 175, color = "darkgreen")

Small particles biomass

PubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb < 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- PubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
PubDf <- PubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBS <- PubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1.2)) + geom_hline(yintercept = 175, color = "darkgreen") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = 950, color = "darkblue") + labs( x = "Small particle mass (norm.)")
pWBS

LubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb >= 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- LubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
LubDf <- LubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBL <- LubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 175, color = "darkgreen") + labs( x = "Large particle mass (norm.)") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = 950, color = "darkblue")
pWBL

For tom and danielle

WBColorMap

pWBPSD

pWBS

pWBL

WBFig5 <- plot_grid(pWBPSD, pWBS,pWBL, nrow = 1, labels = c("B", "C", "D"))
Removed 6 row(s) containing missing values (geom_path).Removed 8 row(s) containing missing values (geom_path).
WBFig5

WBcombined <- plot_grid(WBColorMap + theme(plot.margin = unit(c(0,3,0, 3), "cm")), WBFig5, ncol = 1, labels = c("A", ""))
WBcombined


ggsave("figures/WBModelValidation.png")
Saving 8 x 6 in image

EK60

dataBinned <- read_csv("data/backscatter_table_go7.csv")
dataBinned_01 <- dataBinned %>%
  mutate(timeMex = with_tz(time_bin, tzone = "US/Central") )
startDay <- dataBinned_01$timeMex %>% na.omit %>% min %>% floor_date(unit = "days")
endDay <- dataBinned_01$timeMex %>% na.omit %>% max %>% ceiling_date(unit = "days")
timeBreaks <- seq(from = startDay, to = endDay, by = "12 hours")
timeLabels <- format(timeBreaks)
dataBinned_01 %>% filter(frequency == 18000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -75), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5))

#ggsave("figures/stationP2_EK60_18kOnly.svg")
ggsave("figures/stationP2_EK60_18kOnly.png")
dataBinned_01 %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -75), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
  
  
  facet_wrap(~frequency, ncol = 1)

#ggsave("figures/stationP2_EK60_go7.svg", width = 8, height = 20)
ggsave("figures/stationP2_EK60_go7.png", width = 8, height = 20)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KG1nY3YpCnRoZW1lX3NldCh0aGVtZV9jb3dwbG90KCkpCmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCmBgYAoKCiMgUGFydGljbGVzIE9ubHkKCiMgUmVhZCBJbiBEYXRhCgpgYGB7cn0KYmVzPC0gcmVhZF9jc3YoImRhdGFPdXQvYmlubmVkX0VhY2hTaXplLmNzdiIpCmJkcyA8LSByZWFkX2NzdigiZGF0YU91dC9iaW5uZWRfRGVwdGhTdW1tYXJ5LmNzdiIpCnVlcyA8LSByZWFkX2NzdigiZGF0YU91dC91bmJpbm5lZF9FYWNoU2l6ZS5jc3YiKQp1ZHMgPC0gcmVhZF9jc3YoImRhdGFPdXQvdW5iaW5uZWRfRGVwdGhTdW1tYXJ5LmNzdiIpCmBgYAoKCiMgU3VtbWFyeSBTdGF0aXN0aWNzCmBgYHtyfQpQbG90TlBhcnRpY2xlcyA8LSB1ZHMgJT4lIAogIGdncGxvdChhZXMoeCA9IHRvdF9ucGFydGljbGVzLCB5ID0gZGVwdGgsIGNvbCA9IHByb2ZpbGUpKSArCiBmYWNldF93cmFwKH5wcm9qZWN0KSArCiBnZW9tX3BvaW50KGFscGhhID0gMC4zLCBzaGFwZSA9IDEpICsKc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkKClBsb3ROUGFydGljbGVzCmBgYAoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKRlNHMSA8LSBnYW0odG90X25wYXJ0aWNsZXN+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzIgPC0gZ2FtKHRvdF9ucGFydGljbGVzIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzMgPC0gZ2FtKHRvdF9ucGFydGljbGVzIH4gcyhkZXB0aCwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKI0ZTRzQgPC0gZ2FtKHRvdF9ucGFydGljbGVzfiBzKGRlcHRoLCBrID0gMykgICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCiNzdW1tYXJ5KEZTRzIpCiNzdW1tYXJ5KEZTRzMpCiNzdW1tYXJ5KEZTRzQpCgpzdW1tYXJ5KEZTRzEpJHIuc3EgLSBzdW1tYXJ5KEZTRzIpJHIuc3EKc3VtbWFyeShGU0cyKSRyLnNxIC0gc3VtbWFyeShGU0czKSRyLnNxCnN1bW1hcnkoRlNHMykkci5zcQpgYGAKCkJ1dCB0aGVyZSBpcyBiZXR3ZWVuIHByb2plY3RzOgpgYGB7cn0KUHJvakdhbSA8LSBnYW0odG90X25wYXJ0aWNsZXN+IHMoZGVwdGgsIGsgPSAzKSArIGZhY3Rvcihwcm9qZWN0KSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDApKQoKc3VtbWFyeShQcm9qR2FtKQpgYGAKCmBgYHtyIGZpZy53aWR0aCA9IDEyfQpQbG90UFNEbWFueSA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpKSkgKwogCiAgI2dlb21fcGF0aChhZXMoeCA9IHBzZF9nYW0pKSArIAogICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSwgb3V0bGluZV90eXBlID0gImxvd2VyIikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAuNiwgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDIxOjI1KSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpIAoKUGxvdFBhcnRpY2xlc21hbnkgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9ucGFydGljbGVzLCB5ID0gZGVwdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpKSkgKwogCiAgI2dlb21fcGF0aChhZXMoeCA9IHBzZF9nYW0pKSArIAogICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSwgb3V0bGluZV90eXBlID0gImxvd2VyIikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAuNiwgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDIxOjI1KSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBzY2FsZV94X2xvZzEwKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpQbG90Rmx1eG1hbnkgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9mbHV4X2ZpdCwgeSA9IGRlcHRoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSkpICsKIAogICNnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKyAKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEsIG91dGxpbmVfdHlwZSA9ICJsb3dlciIpICsKICBnZW9tX3BvaW50KGFscGhhID0gLjYsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKCgpwbG90X2dyaWQoCiAgUGxvdFBhcnRpY2xlc21hbnksCiAgUGxvdFBTRG1hbnksCiAgcmVsX3dpZHRocyA9IGMoMiwgMykKICApCgpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzUFNETWFueS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzUFNETWFueS5zdmciKQoKYGBgCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzIgPC0gZ2FtKHBzZCB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0czIDwtIGdhbShwc2QgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0c0IDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSAgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoRlNHMSkKI3N1bW1hcnkoRlNHMikKI3N1bW1hcnkoRlNHMykKc3VtbWFyeShGU0c0KQoKc3VtbWFyeShGU0cxKSRyLnNxIC0gc3VtbWFyeShGU0cyKSRyLnNxCnN1bW1hcnkoRlNHMikkci5zcSAtIHN1bW1hcnkoRlNHMykkci5zcQpzdW1tYXJ5KEZTRzMpJHIuc3EKYGBgCk5vdCBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gUFNEIHdpdGggcmVzcGVjdCB0byB0aW1lLgoKQnV0IHRoZXJlIGlzIGJldHdlZW4gcHJvamVjdHM6CmBgYHtyfQpQcm9qR2FtIDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSArIGZhY3Rvcihwcm9qZWN0KSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDApKQoKc3VtbWFyeShQcm9qR2FtKQpgYGAKCgoKCkkgd29uZGVyIGlmIEkgY2FuIHNob3cgdGhhdCB0aGUgcHJvZmlsZXMgYXJlbid0IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbmx0eSBkaWZmZXJlbnQuIE9yIHRoYXQgdGhleSBhcmUgZm9yIHRoYXQgbWF0dGVyLi4uCkkgdGhpbmsgaW4gdGhhdCBjYXNlLCBJIHJ1biBhIGdhbSB3aXRoIGFuZCB3aXRob3V0IGEgcGFyYW1ldGVyIGZvciBwcm9maWxlLi4uCkFuZCB0aGVuIHF1YW50aWZ5IHRoZSBlZmZlY3Qgc2l6ZSBvZiB0aGF0IHBhcmFtZXRlcgoKT3IgZm9sbG93IHRoaXMgR2F2aW4gU2ltcHNvbiBQb3N0Cmh0dHBzOi8vZnJvbXRoZWJvdHRvbW9mdGhlaGVhcC5uZXQvMjAxNy8xMC8xMC9kaWZmZXJlbmNlLXNwbGluZXMtaS8KCm9yIAphbm92YS5nYW0ge21nY3Z9CgpDYWxjdWxhdGUgZ2FtcyBmb3IgZWFjaCBwcm9maWxlLCBhbmQgdGhlbiBydW4gYW5vdmEuZ2FtIHRvIHNlZSBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuLi4KCmBgYHtyfQpQbG90TlBhcnRpY2xlc0VQIDwtIHVkcyAlPiUgCiAgZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9ucGFydGljbGVzLCB5ID0gZGVwdGgsIGNvbCA9IHByb2plY3QsIHNoYXBlID0gcHJvamVjdCkpICsKIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgI2dlb21fcGF0aChhZXMoeCA9IHRvdF9ucGFydGljbGVzKSkgKwogICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSkgKwpzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygyNTAwLCAwKSkgKyBzY2FsZV94X2xvZzEwKCkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZ3JheTIwIiwgImJyb3duIikpICsKICBsYWJzKHggPSAiUGFydGljbGVzL0wiLCB5ID0gImRlcHRoIChtKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSAKClBsb3ROUGFydGljbGVzRVAKYGBgCgpJIHJlbW92ZWQgb25lIG91dGx5ZXIgZnJvbSBwMTYgZm9yIHZpc3VhbGl6YXRpb24gcHVycG9zZXMgKDMwMCBwYXJ0aWNsZXMvbCBhdCBzdXJmYWNlKQoKYGBge3J9ClBsb3RQU0RFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKwogZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xKSArCnNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDI1MDAsIDApKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJncmF5MjAiLCAiYnJvd24iKSkgICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArIGxhYnMoeSA9ICIiKQoKUGxvdFBTREVQCmBgYAoKSSBtYXkganVzdCBjb3cgdGhlc2UgdG9ndGhlci4KCmBgYHtyIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gNH0KcGxvdF9ncmlkKFBsb3ROUGFydGljbGVzRVAsIFBsb3RQU0RFUCwgcmVsX3dpZHRocyA9IGMoMiwzKSwgbGFiZWxzID0gYygiQSIsICJCIikpCmdnc2F2ZSgiZmlndXJlcy9QYXJ0aWNsZXNBbmRQU0RfRVROUFZzUDE2LnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9QYXJ0aWNsZXNBbmRQU0RfRVROUFZzUDE2LnBuZyIpCmBgYAoKYGBge3J9Cm1haW5QYXJ0aWNsZUNvbXBvbmVudHMgPC0gYmRzICU+JQogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBzZWxlY3QocHJvamVjdCwgcHJvZmlsZSwgZGVwdGgsCiAgICAgICAgIHRvdF9ucGFydGljbGVzLCBzbWFsbF9ucGFydGljbGVzLCBiaWdfbnBhcnRpY2xlcywKICAgICAgICAgdG90X3BzZCA9IHBzZCwgc21hbGxfcHNkLCBiaWdfcHNkLAogICAgICAgICB0b3RfZmx1eF9maXQsIHNtYWxsX2ZsdXhfZml0LCBiaWdfZmx1eF9maXQpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLWMoInByb2plY3QiLCAicHJvZmlsZSIsICJkZXB0aCIpKSAlPiUKICBzZXBhcmF0ZShuYW1lLCBjKCJzaXplIiwgIm1lYXMiKSkgJT4lCiAgbXV0YXRlKG1lYXMgPSByZWNvZGUobWVhcywgbnBhcnRpY2xlcyA9ICJwYXJ0aWNsZXMvTCIpKSAlPiUKICBtdXRhdGUobWVhcyA9IGZhY3RvcihtZWFzLCBsZXZlbHMgPSBjKCJwYXJ0aWNsZXMvTCIsICJmbHV4IiwgInBzZCIpKSkKClBsb3RGbHggPC0gbWFpblBhcnRpY2xlQ29tcG9uZW50cyAlPiUgCiAgZmlsdGVyKG1lYXMgIT0gInBzZCIpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gdmFsdWUsIGNvbCA9IHByb2plY3QsIHNoYXBlID0gcHJvamVjdCkpICsgZmFjZXRfZ3JpZChzaXplIH4gbWVhcywgc2NhbGVzID0gImZyZWVfeCIpICsgZ2VvbV9wb2ludChzaXplID0gMikgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBzY2FsZV94X2xvZzEwKCkgKyB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgc3RyaXAuYmFja2dyb3VuZC55ID0gZWxlbWVudF9ibGFuaygpLCBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIHBsb3QubWFyZ2luID0gdW5pdChjKDcsMCw3LDcpLCAicHQiKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYnJvd24iLCAiZ3JheTIwIikpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTo1KSkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpCgpQbG90UFNEIDwtIG1haW5QYXJ0aWNsZUNvbXBvbmVudHMgJT4lIAogIGZpbHRlcihtZWFzID09ICJwc2QiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHZhbHVlLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArIGZhY2V0X2dyaWQoc2l6ZX5tZWFzLCBzY2FsZXMgPSAiZnJlZV94IikgKyBnZW9tX3BvaW50KHNpemUgPSAyKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYyg3LDcsMjYuNSwwKSwgInB0IikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYnJvd24iLCAiZ3JheTIwIikpICsgIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE6NSkpICsgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikKCnBsb3RfZ3JpZChQbG90Rmx4LCBQbG90UFNELCByZWxfd2lkdGhzID0gYygzLCAyKSkKCmdnc2F2ZSgiZmlndXJlcy9CaWdWc1NtYWxsLnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9CaWdWc1NtYWxsLnBuZyIpCmBgYAoKRmx1eCBzbWFsbCBhbmQgZmx1eCB0b3QgdHJhY2sgc28gY2xvc2VseSBiZWNhdXNlIGFnID4gcHNkLiBzaW5jZSB0aGUgc2l6ZSBkaXN0cmlidXRpb24gb2YgdGhlIGZsdXggc291bGQgYmUgUFNEICsgYWcgKHBzZCBpcyBuZWdhdGl2ZSBpbiB0aGlzIGNhc2UpLiBZbyB1Y2FuIHNlZSB0aGUgdmFyaWFuY2UgYXQgdGhlIG9uZSBkZXB0aCB3aGVyZSBwc2QgaXMgZmxhdGVzdCBhdCB0aGUgdmVyeSB0b3AuCgpgYGB7cn0KZWdfZGF0YWxpbmUgPC0gYmRzICU+JSAKICBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIsIGRlcHRoID09IDE2Mi41KQplZ19zbG9wZSA9ICBlZ19kYXRhbGluZSAlPiUgcHVsbChwc2QpCmVnX2ljcCA9IGVnX2RhdGFsaW5lICU+JSBwdWxsKGljcCkKZWdfdm9sID0gZWdfZGF0YWxpbmUgJT4lIHB1bGwodm9sKQoKZWdfZGF0YWJsb2NrIDwtIGJlcyAlPiUKICBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIsIGRlcHRoID09IDE2Mi41KQoKCmVnX2xiID0gZWdfZGF0YWJsb2NrJGxiCmVnX2JpbnNpemUgPSBlZ19kYXRhYmxvY2skYmluc2l6ZQplZ19ubnAgPSBleHAoZWdfaWNwICsgbG9nKGVnX2xiKSAqIGVnX3Nsb3BlKQoKZWdfbnAgPSBlZ19ubnAgKiBlZ19iaW5zaXplCmVnX3RwID0gZWdfbnAgKiBlZ192b2wKZWdfZGYgPC0gdGliYmxlKGxiID0gZWdfbGIsIG5fbnBhcnRpY2xlcyA9IGVnX25ucCwgbnBhcnRpY2xlcyA9IGVnX25wLCBUb3RhbFBhcnRpY2xlcyA9IGVnX3RwKQoKCkVnTk5QIDwtIGVnX2RhdGFibG9jayAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IG5fbnBhcnRpY2xlcykpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgCiAgZ2VvbV9wYXRoKGRhdGEgPSBlZ19kZikgKyBsYWJzKHkgPSAiQmluc2l6ZSAmIFZvbHVtZSBOb3JtYWxpemVkIFxuIFBhcnRpY2xlcyAoIy9ML21tKSIpCgpFZ05QIDwtIGVnX2RhdGFibG9jayAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IG5wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIk5vcm1hbGl6ZWQgUGFydGljbGVzIikKCkVnVFAgPC0gZWdfZGF0YWJsb2NrICU+JQogIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gVG90YWxQYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyggeSA9ICJUb3RhbCBQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIikKCnBsb3RfZ3JpZChFZ05OUCwgRWdUUCwgbGFiZWxzID0gYygiQSIsICJCIikpCmdnc2F2ZSgiZmlndXJlcy9FeGFtcGxlUFNEMTYzbS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvRXhhbXBsZVBTRDE2M20uc3ZnIikKCmBgYAoKIyBTbW9vdGggZmx1eCBhbmQgdW0gZGlzYWdncmVnYXRpb24uCgpgYGB7cn0KYmRzICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IEZsdXhfU21vb3RoLCBjb2wgPSBmYWN0b3IodGltZSkpKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpCmBgYAoKCgoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKRlNHMSA8LSBnYW0oRmx1eF9TbW9vdGh+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzIgPC0gZ2FtKEZsdXhfU21vb3RoIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzMgPC0gZ2FtKEZsdXhfU21vb3RoIH4gcyhkZXB0aCwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKc3VtbWFyeShGU0cxKQpzdW1tYXJ5KEZTRzIpCnN1bW1hcnkoRlNHMykKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcQpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EKc3VtbWFyeShGU0czKSRyLnNxCmBgYAoKYGBge3J9CmJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSAlPiUgc2VsZWN0KHByb2ZpbGUsIGRlcHRoLCBGbHV4X1Ntb290aCkgJT4lIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBwcm9maWxlLCB2YWx1ZXNfZnJvbSA9IEZsdXhfU21vb3RoKQpgYGAKClNvbWV0aGluZyBpcyBvZmYuIEFsbCBvZiB0aGUgZmx1eCBwcm9maWxlcyBhcmUgaWRlbnRpY2FsLgpTa2lwIHRoaXMKYGBge3J9CmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdDEgPC0gYmRzICU+JSAjZmlsdGVyKERGUCA+IDEpICU+JSAjZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gREZQLCBjb2wgPSBmYWN0b3IodGltZSksIHNoYXBlID0gZmFjdG9yKHRpbWUpKSkgKyBmYWNldF93cmFwKH5wcm9qZWN0KSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIHhsaW0oYygwLjUsIDEuNSkpKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArCiAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKHJlcCgiYmxhY2siLCA1KSwgcmVwKCJibHVlIiwgNSkpKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSByZXAoMTo1LCAyKSkKCnBsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgpXaGF0IHRoZSBoZWNrIGlzIGdvaW5nIG9uIHdpdGggREZQIGhlcmUuIFdoeSBpcyBpdCB1c3VhbGx5ID4gMSBzaG91bGRuJ3QgaXQgYmUgbGVzcyB0aGFuIDEgd2hlbiBmbHV4IGlzIGRlY3JlYXNpbmc/ClRoaXMgdmVyeSBkZWVwIGluY3JlYXNpbmcgZmx1eCBzZWVtcyBpbXByb2JhYmxlIHRvIG1lLgpMZXRzIGNoZWNrIHRoZSBzbW9vdGhzLiBPciBvbmx5IGdvIHRvIDEwMDBtLgoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0Rmx4IDwtIGJkcyAlPiUgI2ZpbHRlcihERlAgPiAxKSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IEZsdXhfU21vb3RoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkrCiAgZ2VvbV9wYXRoKCkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDI1MDAsIDApKSsKICBzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIgb2YgRGF5IiwgYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgY29sb3JzID0gYygiYmxhY2siLCAiYmx1ZSIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAiYmxhY2siKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArCmxhYnMoeCA9IGJxdW90ZShTbW9vdGhlZH5GbHV4fijCtW1vbH5DL21eMi9kKSkpICsKICBnZW9tX3JlY3QoZGF0YSA9IGRhdGEuZnJhbWUocHJvamVjdCA9ICJFVE5QIiksIGFlcyh4bWluID0gMjAsIHhtYXggPSAxODAsIHltaW4gPSA3NSwgeW1heCA9IDUwMCksIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpCgoKCnBsdEZseE5vTGVnZW5kIDwtIHBsdEZseCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnBsdEZseAojcGxvdGx5OjpnZ3Bsb3RseShwbHQxKQpgYGAKCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdEZseFpvb20gPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIgJiBkZXB0aCA8PSA1MDAgJiBkZXB0aCA+PSA3NSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgKyBnZW9tX3BvaW50KHNpemUgPSAzLCBzdHJva2UgPSAxKSsKICBnZW9tX3BhdGgoKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkrCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBjKHNlcShmcm9tID0gMjAsIHRvID0gNTAsIGJ5ID0gMTApLCBzZXEoZnJvbSA9IDYwLCB0byA9IDE4MCwgYnkgPSAyMCkpLCBsaW1pdHMgPSBjKDIwLCAxODApKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsKbGFicyh4ID0gIlNtb290aGVkIEZsdXgiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnBsdEZseFpvb20KI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgoKCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdERlbHRhMyA8LSBiZHMgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkrCiAgZ2VvbV9wYXRoKCkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDI1MDAsIDApKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtNC41LCAxKSkgKwogICNzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIGxhYnMoeCA9IGJxdW90ZSgoREYvRFopXnsxLzV9fijCtW1vbEMvbV4zL2QpXnsxLzV9KSkgKyB0aGVtZShsZWdlbmQucG9zID0gIm5vbmUiKQogICNsYWJzKHggPSAiKERGL0RaKSBeIDEvNSAowrVtb2wgQy9tXjMvZCkgXiAxLzUiKQoKcGx0RGVsdGEzCiNwbG90bHk6OmdncGxvdGx5KHBsdDFwb3MpCmBgYAoKKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLCAwLCAwLCAwKSwgdW5pdHMgPSAiY20iKSkKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoID0gOH0KI3Bsb3RfZ3JpZChwbHRGbHhOb0xlZ2VuZCwgcGx0Rmx4Wm9vbSwgcGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQpCgpwbHRGbHhMZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbHRGbHggKyB0aGVtZShsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCA0MCwgMTApKSkKCnBnVG9wIDwtIHBsb3RfZ3JpZChwbHRGbHhOb0xlZ2VuZCwgcGx0Rmx4Wm9vbSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDEsIDAsIDMsIDApLCB1bml0cyA9ICJjbSIpKSwgcmVsX3dpZHRocyA9IGMoMiwgMSksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQpwZ0JvdHRvbSA8LSBwbG90X2dyaWQocGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQgLCByZWxfd2lkdGhzID0gYygzLCAxKSwgbGFiZWxzID0gYygiQyIsICIiKSkKcGdCb3RoIDwtIHBsb3RfZ3JpZChwZ1RvcCwgcGdCb3R0b20sIG5jb2wgPSAxKQoKcGdCb3RoCgpnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9GbHV4RGVlcERpdmUuc3ZnIikKCmBgYAoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGggPSA4fQojcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kLCBwbHRGbHhab29tLCBwbHREZWx0YTMsIHBsdEZseExlZ2VuZCkKCnBsdEZseExlZ2VuZCA8LSBnZXRfbGVnZW5kKHBsdEZseCArIHRoZW1lKGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDAsIDQwLCAxMCkpKQoKcGdUb3AgPC0gcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kICsgeWxpbShjKDEwMDAsIDApKSwgcGx0Rmx4Wm9vbSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDEsIDAsIDMsIDApLCB1bml0cyA9ICJjbSIpKSwgcmVsX3dpZHRocyA9IGMoMiwgMSksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQpwZ0JvdHRvbSA8LSBwbG90X2dyaWQocGx0RGVsdGEzICsgeWxpbShjKDEwMDAsIDApKSwgcGx0Rmx4TGVnZW5kICwgcmVsX3dpZHRocyA9IGMoMywgMSksIGxhYmVscyA9IGMoIkMiLCAiIikpCnBnQm90aCA8LSBwbG90X2dyaWQocGdUb3AsIHBnQm90dG9tLCBuY29sID0gMSkKCnBnQm90aAoKZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaGFsbG93RGl2ZS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvRmx1eFNoYWxsb3dEaXZlLnN2ZyIpCgpgYGAKClRlc3QgZm9yIGRheSB0byBkYXkgYW5kIGhvdXJseSB2YXJpYWJpbGl0eQpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpERkcxIDwtIGdhbShERi9EWn4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHMiA8LSBnYW0oREYvRFogfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHMyA8LSBnYW0oREYvRFogfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KERGRzEpCnN1bW1hcnkoREZHMikKc3VtbWFyeShERkczKQoKc3VtbWFyeShERkcxKSRyLnNxIC0gc3VtbWFyeShERkcyKSRyLnNxCnN1bW1hcnkoREZHMikkci5zcSAtIHN1bW1hcnkoREZHMykkci5zcQpzdW1tYXJ5KERGRzMpJHIuc3EKYGBgCgpgYGB7cn0KcGxvdChERkcxKQpgYGAKCiNPc3BzCgoodSBtb2wgQyAvIG1eMyAvIGRheSkKYGBge3J9CmJkcyAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3Qob3Nwc0RaLCAzKSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgKyBmYWNldF93cmFwKH5wcm9qZWN0KSArIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMjUwMCwgMCkpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKyAgIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgbGFicyh4ID0gYnF1b3RlKCJGbHV4IFNpemUgU2hpZnQifs68bW9sL21eMy9kYXkpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKQoKI2dnc2F2ZSgiLi5maWd1cmVzL0ZsdXhTaXplU2hpZnQuc3ZnIgoKIGdnc2F2ZSgiZmlndXJlcy9GbHV4U2l6ZVNoaWZ0LnBuZyIpCiBnZ3NhdmUoImZpZ3VyZXMvRmx1eFNpemVTaGlmdC5zdmciKQpgYGAKCmBgYHtyfQpiZHNBZGRUaW1lIDwtIGJkcyAlPiUKICBtdXRhdGUoSG91ciA9IGhvdXIodGltZSksIERheSA9IGRheSh0aW1lKSkKCk9aRzEgPC0gZ2FtKG9zcHNEWiB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCk9aRzIgPC0gZ2FtKG9zcHNEWiB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpPWkczIDwtIGdhbShvc3BzRFogfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KE9aRzEpCnN1bW1hcnkoT1pHMikKc3VtbWFyeShPWkczKQoKc3VtbWFyeShPWkcxKSRyLnNxIC0gc3VtbWFyeShPWkcyKSRyLnNxCnN1bW1hcnkoT1pHMikkci5zcSAtIHN1bW1hcnkoT1pHMykkci5zcQpzdW1tYXJ5KE9aRzMpJHIuc3EKYGBgCgpgYGB7cn0KYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBvc3BzRFopKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoNTAwLCAwKSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKQpgYGAKCiMgVHJhcCBkYXRhCmBgYHtyfQp0cmFwRmx1eDMgPC0gcmVhZF9jc3YoImRhdGFPdXQvZmx1eE1TX2Rpc3RpbGxlZC5jc3YiKQpVVlBGbHV4Q29tYiA8LSByZWFkX2NzdigiZGF0YU91dC9Db21iaW5lZFByb2ZpbGVGbHV4RXN0X0RTLmNzdiIpCgpgYGAKCmBgYHtyfQp0cmFwRmx1eDMKYGBgCmBgYHtyfQpVVlBGbHV4Q29tYgpgYGAKCgpgYGB7cn0KCmZsdXhNU19kaXN0aWxsZWRfdG9QbG90IDwtIHRyYXBGbHV4MyAlPiUKICBtdXRhdGUoU2FtcGxlVHlwZSA9IHJlY29kZShTYW1wbGVUeXBlLCBgcGx1cy5wYCA9ICJwbHVzLXBhcnRpY2xlcyIsIHRvcCA9ICJ0b3AtY29sbGVjdG9yIikpCmBgYAoKYGBge3J9ClVWUEZsdXhDb21iICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoKSkgICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAyMDApKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IERlcHRoLCB4ID0gQ19mbHV4X3Vtb2wsIGZpbGwgPSBTYW1wbGVUeXBlLCBzaGFwZSA9IFRyYXBUeXBlKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIHN0cm9rZSA9IDEsIHNpemUgPSA1LCBkYXRhID0gZmx1eE1TX2Rpc3RpbGxlZF90b1Bsb3QpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gRmx1eCksIHNpemUgPSAzLCBzaGFwZSA9IDIxLCBjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IC0xLCB5ID0gLTEsIHNpemUgPSAiVVZQIikpICsgIyBkdW1teSBwb2ludCBmb3IgdGhlIGxlZ2VuZApzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyNSwgMjIpKSsKICBzY2FsZV9zaXplX21hbnVhbCh2YWx1ZXMgPSAxLCBuYW1lID0gIiIpICsKICB5bGFiKCJEZXB0aCAobSkiKSArIHhsYWIoIkZsdXggwrVtb2xDL21eMi9kYXkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaGFwZSA9IDIxKSkpICsKICB0aGVtZV9jb3dwbG90KCkgKyAKICB0aGVtZSgKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNSwgMC40KSwKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKC0xMCwgNSwgMTAsIDUpCiAgKSArCiAgZ2VvbV9yZWN0KGRhdGEgPSBkYXRhLmZyYW1lKHByb2plY3QgPSAiRVROUCIpLCBhZXMoeG1pbiA9IDE1LCB4bWF4ID0gMzIsIHltaW4gPSA0NSwgeW1heCA9IDE5NSksIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnN2ZyIpCmBgYAojIyBXZWJlciBCaWFuY2hpIEZpZ3MKCgoKCmBgYHtyfQpTYW1lR2FtIDwtIGdhbShUb3RhbFBhcnRpY2xlcyB+cyhsb2cobGIpLCBsb2coZGVwdGgpLCBieSA9IGZhY3Rvcih0aW1lKSksIG9mZnNldCA9IGxvZyh2b2wgKiBiaW5zaXplKSwgZmFtaWx5ID0gbmIoKSwKICAgIGRhdGEgPSBiZXMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikpCmBgYAoKYGBge3J9CmJlc0UgPC0gYmVzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpCgpsYl9uZXcgPC0gZXhwKHNlcShmcm9tID0gbG9nKDAuMSksIHRvID0gbG9nKDIuMSksIGJ5ID0gMC4wNSkpCnViX25ldyA8LSBsZWFkKGxiX25ldykKYmluc2l6ZV9uZXcgPC0gdWJfbmV3IC0gbGJfbmV3CgpsYmJzIDwtIHRpYmJsZShsYiA9IGxiX25ldywgdWIgPSB1Yl9uZXcsIGJpbnNpemUgPSBiaW5zaXplX25ldykKCkV4cGFuZGVkIDwtIGV4cGFuZF9ncmlkKGxiID0gZXhwKHNlcShmcm9tID0gbG9nKDAuMSksIHRvID0gbG9nKDIpLCBieSA9IDAuMDUpKSwgZGVwdGggPSBzZXEoZnJvbSA9IDIwLCB0byA9IDIwMDAsIGJ5ID0gMjApLCB0aW1lID0gYXMuZmFjdG9yKHVuaXF1ZShiZXNFJHRpbWUpKSkgJT4lIGxlZnRfam9pbihsYmJzLCBieSA9ICJsYiIpCgpQcmVkIDwtIGV4cChwcmVkaWN0KFNhbWVHYW0sIEV4cGFuZGVkKSkKVG9QbG90IDwtIGJpbmRfY29scyhFeHBhbmRlZCwgbm5wYXJ0aWNsZXMgPSBQcmVkKSAlPiUgbXV0YXRlKHRpbWUgPSBhcy5jaGFyYWN0ZXIodGltZSkpICU+JSBtdXRhdGUobnBhcnRpY2xlcyA9IG5ucGFydGljbGVzICogYmluc2l6ZSkKYGBgCgpgYGB7cn0KVG9QbG90ICU+JSBmaWx0ZXIobGIgPD0gMikgJT4lICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IGRlcHRoLCBmaWxsID0gbG9nMTAobm5wYXJ0aWNsZXMpLCB6ID0gbG9nMTAobm5wYXJ0aWNsZXMpKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfbG9nMTAoKSAgKyBmYWNldF93cmFwKH50aW1lKSArIGdlb21fY29udG91cihjb2xvciA9ICJibGFjayIpCmBgYApgYGB7cn0KbWVhbkJlc2UgPC0gVG9QbG90ICU+JSBmaWx0ZXIobGIgPD0gMikgJT4lIGdyb3VwX2J5KGxiLCBkZXB0aCkgJT4lIHN1bW1hcml6ZShucGFydGljbGVzID0gbWVhbihucGFydGljbGVzKSwgbm5wYXJ0aWNsZXMgPSBtZWFuKG5ucGFydGljbGVzKSkKCldCQ29sb3JNYXAgPC0gbWVhbkJlc2UlPiUKICAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBkZXB0aCwgZmlsbCA9IGxvZzEwKG5ucGFydGljbGVzKSwgeiA9IGxvZzEwKG5ucGFydGljbGVzKSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhuYW1lID0gImxvZzEwKG51bWJlciBkZW5zaXR5IFxuIChub3JtYWxpemVkKSkiKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9sb2cxMCgpICsgZ2VvbV9jb250b3VyKGNvbG9yID0gImJsYWNrIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOTUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCldCQ29sb3JNYXAKYGBgCkF2ZXJhZ2Ugb2YgZXZlcnl0aGluZwoKYGBge3J9Cm1lYW5CZXNlMDQzIDwtIFRvUGxvdCAlPiUgZmlsdGVyKGxiIDw9IDIsIHRpbWUgPT0gIjIwMTctMDEtMTMgMTE6NTE6MzEiKQoKbWVhbkJlc2UwNDMlPiUKICAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBkZXB0aCwgZmlsbCA9IGxvZzEwKG5ucGFydGljbGVzKSwgeiA9IGxvZzEwKG5ucGFydGljbGVzKSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX2NvbnRvdXIoY29sb3IgPSAiYmxhY2siKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikKYGBgCkp1c3QgMDQzCgpgYGB7cn0KbWJHYW0gPC0gbWVhbkJlc2UgJT4lIGdyb3VwX2J5KGRlcHRoKSAgJT4lIG5lc3QoKSAlPiUKICBtdXRhdGUobW9kID0gbWFwKGRhdGEsIH5nYW0obG9nKG5ucGFydGljbGVzKSB+IGxvZyhsYiksIGZhbWlseSA9IGdhdXNzaWFuKCksIGRhdGEgPSAuKSkpICU+JSAKICBtdXRhdGUocHNkID0gbWFwX2RibChtb2QsIH5zdW1tYXJ5KC4pJHAuY29lZmZbMl0pKQpgYGAKCmBgYHtyfQptYkdhbSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gIDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpgYGAKCmBgYHtyfQptYkdhbSA8LSBtZWFuQmVzZTA0MyAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgbmVzdCgpICU+JQogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfmdhbShsb2cobm5wYXJ0aWNsZXMpIH4gbG9nKGxiKSwgZmFtaWx5ID0gZ2F1c3NpYW4oKSwgZGF0YSA9IC4pKSkgJT4lIAogIG11dGF0ZShwc2QgPSBtYXBfZGJsKG1vZCwgfnN1bW1hcnkoLikkcC5jb2VmZlsyXSkpCmBgYAoKYGBge3J9CnBXQlBTRCA8LSBtYkdhbSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9ICA5NTAsIGNvbG9yID0gImRhcmtibHVlIikKcFdCUFNECmBgYAoKCiMjIEZpZyA1IFdCCgpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gcHNkX3NlZyAqIDIsIHhtYXggPSBwc2RfZ2FtICsgcHNkX3NlZyAqIDIsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcmliYm9uKGFscGhhID0gMC4yKSArIGxhYnMoeCA9ICJQU0Qgc2xvcGUiKQoKQWxsIG9mIHRoZW0KCmBgYHtyfQpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gcHNkX3NlZyAqIDIsIHhtYXggPSBwc2RfZ2FtICsgcHNkX3NlZyAqIDIsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcmliYm9uKGFscGhhID0gMC4yKSArIGxhYnMoeCA9ICJQU0Qgc2xvcGUiKQpgYGAKMDQzIG9ubHkKCmBgYHtyfQpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCwgZGVwdGggPiAxNzUpICU+JSBnZ3Bsb3QoYWVzKHggPSBzbWFsbF9iaW92b2x1bWUsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcG9pbnQoKQpgYGAKCmBgYHtyfQp1YkRmMCA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkKdWJEZiA8LSB1YkRmMCAlPiUgZ3JvdXBfYnkodGltZSwgZGVwdGgpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBzdW0odWJpb21hc3MpKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoZGVwdGgpCnBob3RpY0Jpb21hc3MgPC0gdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQp1YkRmIDwtIHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGggLCBncm91cCA9IHRpbWUsIGNvbCA9IHRpbWUpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKQpgYGAKCgogCmBgYHtyfQp1YkRmIDwtIFRvUGxvdCAlPiUgbXV0YXRlKHViaW9tYXNzID0gbnBhcnRpY2xlcyAqIGxiIF4gYWdfZ2xvYmFsKSAlPiUgZ3JvdXBfYnkodGltZSwgZGVwdGgpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBzdW0odWJpb21hc3MpKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgc3VtbWFyaXNlKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpCnBob3RpY0Jpb21hc3MgPC0gdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQp1YkRmIDwtIHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikKYGBgCgoKIyMjIFNtYWxsIHBhcnRpY2xlcyBiaW9tYXNzCgpgYGB7cn0KUHViRGYgPC0gVG9QbG90ICU+JSBtdXRhdGUodWJpb21hc3MgPSBucGFydGljbGVzICogbGIgXiBhZ19nbG9iYWwpICU+JSBmaWx0ZXIobGIgPCAwLjUpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSBQdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQpQdWJEZiA8LSBQdWJEZiAlPiUgbXV0YXRlKG5iaW9tYXNzID0gdWJpb21hc3MvcGhvdGljQmlvbWFzcykKcFdCUyA8LSBQdWJEZiAlPiUgZ2dwbG90KGFlcyh4ID0gbmJpb21hc3MsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsMS4yKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGxhYnMoIHggPSAiU21hbGwgcGFydGljbGUgbWFzcyAobm9ybS4pIikKcFdCUwpgYGAKCmBgYHtyfQpMdWJEZiA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkgJT4lIGZpbHRlcihsYiA+PSAwLjUpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSBMdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQpMdWJEZiA8LSBMdWJEZiAlPiUgbXV0YXRlKG5iaW9tYXNzID0gdWJpb21hc3MvcGhvdGljQmlvbWFzcykKcFdCTCA8LSBMdWJEZiAlPiUgZ2dwbG90KGFlcyh4ID0gbmJpb21hc3MsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsMSkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGxhYnMoIHggPSAiTGFyZ2UgcGFydGljbGUgbWFzcyAobm9ybS4pIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGNvbG9yID0gImdyYXk1MCIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gOTUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCnBXQkwKYGBgCgpGb3IgdG9tIGFuZCBkYW5pZWxsZQpgYGB7cn0KV0JDb2xvck1hcApwV0JQU0QKcFdCUwpwV0JMCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0PTN9CldCRmlnNSA8LSBwbG90X2dyaWQocFdCUFNELCBwV0JTLHBXQkwsIG5yb3cgPSAxLCBsYWJlbHMgPSBjKCJCIiwgIkMiLCAiRCIpKQpXQkZpZzUKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0ID0gNiwgZmlnLndpZHRoID0gOH0KV0Jjb21iaW5lZCA8LSBwbG90X2dyaWQoV0JDb2xvck1hcCArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAsMywwLCAzKSwgImNtIikpLCBXQkZpZzUsIG5jb2wgPSAxLCBsYWJlbHMgPSBjKCJBIiwgIiIpKQpXQmNvbWJpbmVkCgpnZ3NhdmUoImZpZ3VyZXMvV0JNb2RlbFZhbGlkYXRpb24ucG5nIikKYGBgCgoKIyMgRUs2MAoKYGBge3J9CmRhdGFCaW5uZWQgPC0gcmVhZF9jc3YoImRhdGEvYmFja3NjYXR0ZXJfdGFibGVfZ283LmNzdiIpCmBgYAoKYGBge3J9CmRhdGFCaW5uZWRfMDEgPC0gZGF0YUJpbm5lZCAlPiUKICBtdXRhdGUodGltZU1leCA9IHdpdGhfdHoodGltZV9iaW4sIHR6b25lID0gIlVTL0NlbnRyYWwiKSApCmBgYAoKYGBge3J9CnN0YXJ0RGF5IDwtIGRhdGFCaW5uZWRfMDEkdGltZU1leCAlPiUgbmEub21pdCAlPiUgbWluICU+JSBmbG9vcl9kYXRlKHVuaXQgPSAiZGF5cyIpCmVuZERheSA8LSBkYXRhQmlubmVkXzAxJHRpbWVNZXggJT4lIG5hLm9taXQgJT4lIG1heCAlPiUgY2VpbGluZ19kYXRlKHVuaXQgPSAiZGF5cyIpCnRpbWVCcmVha3MgPC0gc2VxKGZyb20gPSBzdGFydERheSwgdG8gPSBlbmREYXksIGJ5ID0gIjEyIGhvdXJzIikKdGltZUxhYmVscyA8LSBmb3JtYXQodGltZUJyZWFrcykKYGBgCgoKYGBge3J9CmRhdGFCaW5uZWRfMDEgJT4lIGZpbHRlcihmcmVxdWVuY3kgPT0gMTgwMDApICU+JSBnZ3Bsb3QoYWVzKHggPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCBmaWxsID0gdmFsdWUpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsaW1pdHMgPSBjKC0xNjUsIC03NSksIG9vYiA9IHNjYWxlczo6c3F1aXNoKSArCiAgc2NhbGVfeF9kYXRldGltZShicmVha3MgPSB0aW1lQnJlYWtzLCBkYXRlX2xhYmVscyA9ICIlZDo6JUgiKSArIGxhYnMoeCA9ICJkYXk6OmhvdXIiLCB5ID0gImRlcHRoIChtKSIsIGZpbGwgPSAiYmFja3NjYXR0ZXIgKGRCKSIpICsgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41KSkKCiNnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfMThrT25seS5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfMThrT25seS5wbmciKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MjAsIGZpZy53aWR0aCA9IDh9CmRhdGFCaW5uZWRfMDEgJT4lIGdncGxvdChhZXMoeCA9IHRpbWVNZXgsIHkgPSBkZXB0aF9iaW4sIGZpbGwgPSB2YWx1ZSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGxpbWl0cyA9IGMoLTE2NSwgLTc1KSwgb29iID0gc2NhbGVzOjpzcXVpc2gpICsKICBzY2FsZV94X2RhdGV0aW1lKGJyZWFrcyA9IHRpbWVCcmVha3MsIGRhdGVfbGFiZWxzID0gIiVkOjolSCIpICsgbGFicyh4ID0gImRheTo6aG91ciIsIHkgPSAiZGVwdGggKG0pIiwgZmlsbCA9ICJiYWNrc2NhdHRlciAoZEIpIikgKyB0aGVtZV9idygpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUpKSArCiAgCiAgCiAgZmFjZXRfd3JhcCh+ZnJlcXVlbmN5LCBuY29sID0gMSkKCiNnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfZ283LnN2ZyIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gMjApCmdnc2F2ZSgiZmlndXJlcy9zdGF0aW9uUDJfRUs2MF9nbzcucG5nIiwgd2lkdGggPSA4LCBoZWlnaHQgPSAyMCkKYGBg